<?php //-->
/*
 * This file is part a custom application package.
 * (c) 2011-2012 Christian Blanquera <cblanquera@openovate.com>
 */
class Vote extends Eden_Class {
	/* Constants
	-------------------------------*/
	/* Public Properties
	-------------------------------*/
	/* Protected Properties
	-------------------------------*/
	protected $_database 	= NULL;

	/* Private Properties
	-------------------------------*/
	/* Magic
	-------------------------------*/
	public static function i() {
		return self::_getSingleton(__CLASS__);
	}
	
	public function __construct(Eden $app = NULL, $key = NULL) {
		if(is_null($app)) {
			$app = Eden::i()->getActiveApp();
		}
		
		$this->_database 	= $app->database($key);
	}
	
	/* Public Methods
	-------------------------------*/
	/**
	 * Returns the vote count for a post
	 *
	 * @param int|string
	 * @return int
	 */
	public function getVotes($post) {
		Vote_Error::i()->argument(1, 'string', 'int');
		
		if(!is_numeric($post)) {
			$post = $this->_database->getRow('post', 'post_slug', $post);
			$post = $post['post_id'];
		}
		
		$votes = $this->_database
			->search('vote')
			->setColumns('SUM(vote_value) as votes')
			->filterByVotePost($post)
			->getRow('votes');
			
		return $votes ? $votes : 0;
	}
	
	/**
	 * vote up a post
	 *
	 * @param int|string
	 * @param int|string
	 * @return this
	 */
	public function voteUp($post, $user) {
		Vote_Error::i()
			->argument(1, 'string', 'int')
			->argument(2, 'string', 'int');
		
		if(!is_numeric($post)) {
			$post = $this->_database->getRow('post', 'post_slug', $post);
			$post = $post['post_id'];
		}
		
		if(!is_numeric($user)) {
			$user = $this->_database->getRow('user', 'user_slug', $user);
			$user = $user['user_id'];
		}
		
		$vote = $this->_database
			->search('vote')
			->filterByVotePost($post)
			->filterByVoteUser($user)
			->getRow();
		
		if(!$vote) {
			$this->_database->insertRow('vote', array(
				'vote_post' 	=> $post,
				'vote_user' 	=> $user,
				'vote_value' 	=> 1));
			
			return $this;
		}
		
		$filter = 'vote_post = '.$post.' AND vote_user = '.$user;
		$this->_database->updateRows('vote', array('vote_value' => 1), $filter);
		
		return $this;
	}
	
	/**
	 * vote down a post
	 *
	 * @param int|string
	 * @param int|string
	 * @return this
	 */
	public function voteDown($post, $user) {
		Vote_Error::i()
			->argument(1, 'string', 'int')
			->argument(2, 'string', 'int');
		
		if(!is_numeric($post)) {
			$post = $this->_database->getRow('post', 'post_slug', $post);
			$post = $post['post_id'];
		}
		
		if(!is_numeric($user)) {
			$user = $this->_database->getRow('user', 'user_slug', $user);
			$user = $user['user_id'];
		}
		
		$vote = $this->_database
			->search('vote')
			->filterByVotePost($post)
			->filterByVoteUser($user)
			->getRow();
		
		if(!$vote) {
			$this->_database->insertRow('vote', array(
				'vote_post' 	=> $post,
				'vote_user' 	=> $user,
				'vote_value' 	=> -1));
			
			return $this;
		}
		
		$filter = 'vote_post = '.$post.' AND vote_user = '.$user;
		$this->_database->updateRows('vote', array('vote_value' => -1), $filter);
		
		return $this;
	}
	
	/**
	 * installs the relation table
	 *
	 * @return this
	 */
	public function install() {
		$this->_database->query(self::$_schema);
		return $this;
	}
	
	
	
	/* Protected Methods
	-------------------------------*/
	/* Private Methods
	-------------------------------*/
	/* Long Data
	-------------------------------*/
	private static $_schema = 
		'CREATE TABLE IF NOT EXISTS `vote` (
		  `vote_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
		  `vote_post` int(11) unsigned NOT NULL,
		  `vote_user` int(11) unsigned NOT NULL,
		  `vote_value` int(1) NOT NULL DEFAULT \'0\',
		  PRIMARY KEY (`vote_id`),
		  KEY `vote_post` (`vote_post`),
		  KEY `vote_user` (`vote_user`)
		) ENGINE=InnoDB DEFAULT CHARSET=utf8;';
}

/**
 * Vote Error
 */
class Vote_Error extends Eden_Error {
	/* Constants
	-------------------------------*/
	/* Public Properties
	-------------------------------*/
	/* Protected Properties
	-------------------------------*/
	/* Private Properties
	-------------------------------*/
	/* Get
	-------------------------------*/
	public static function i($message = NULL, $code = 0) {
		$class = __CLASS__;
		return new $class($message, $code);
	}
	
	/* Magic
	-------------------------------*/
	/* Public Methods
	-------------------------------*/
	/* Protected Methods
	-------------------------------*/
	/* Private Methods
	-------------------------------*/
}